﻿using System;
using System.Diagnostics.Contracts;
using System.Threading.Tasks;
using Epi.Data;

namespace CDC.SampleShell.Infrastructure
{
    /// <summary>
    /// Sql DB logger intended for use as a logging mechanism in SQL server databases. Assumes UpdateLog table exists prior to being called.
    /// </summary>
    /// <remarks>
    /// Singleton pattern
    /// </remarks>
    public sealed class DbLogger
    {
        private static DbLogger _instance = new DbLogger();

        private IDbDriver _database;
        private string _version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
        private string _user = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
        private string _macAddress = CDC.SampleShell.Common.GetMacAddress();

        public static IDbDriver Database
        {
            private get
            {
                return Instance._database;
            }
            set
            {
                if (Instance._database != null)
                {
                    throw new InvalidOperationException();
                }
                else
                {
                    Instance._database = value;
                }
            }
        }

        static DbLogger()
        {
        }

        private DbLogger()
        {
        }

        public async void Log(string description)
        {
            Contract.Requires(description != null);

            if (_database.ToString().Contains("Epi.Data.Office.AccessDatabase", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            Query insertQuery = _instance._database.CreateQuery("INSERT INTO [UpdateLog] (UDate, Version, UserName, MACADDR, Description) VALUES (CURRENT_TIMESTAMP, @Version, @User, @MACADDR, @Description)");

            insertQuery.Parameters.Add(new QueryParameter("@Version", System.Data.DbType.String, _instance._version));
            insertQuery.Parameters.Add(new QueryParameter("@User", System.Data.DbType.String, _instance._user));
            insertQuery.Parameters.Add(new QueryParameter("@MACADDR", System.Data.DbType.String, _instance._macAddress));
            insertQuery.Parameters.Add(new QueryParameter("@Description", System.Data.DbType.String, description));

            await Task.Factory.StartNew(() =>
            {
                try
                {
                    int rows = _instance._database.ExecuteNonQuery(insertQuery);
                }
                catch (Exception)
                {
                    // do nothing, don't let this crash the app
                }
            });
        }

        public static DbLogger Instance
        {
            get
            {
                return _instance;
            }
        }
    }
}
